package Model;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;

/**
 *
 * @author kiko
 */
public class CMessageReceiver extends Thread {
    private Socket connection;
    private String message;
    private BufferedReader in;
    private DataOutputStream out;
    private ArrayList<Socket> serverList;
    private AtendeCliente atendeCliente;
    
    public CMessageReceiver(Socket conection, AtendeCliente atendeCliente) {
        this.connection = conection;
        this.serverList = atendeCliente.getServerList();
        this.atendeCliente = atendeCliente;
        try {
            in = new BufferedReader(new InputStreamReader(conection.getInputStream()));
            out = new DataOutputStream(conection.getOutputStream());
        } catch (IOException e) {
            System.out.println("Erro ao tentar instanciar CMessageReceiver");
        }
    }

    @Override
    public void run() {
        try {
            interpretMessage(in, out);
        } catch (IOException ex) {
            System.out.println("Erro ao tentar interpretar mensagem de cliente");
        }
    }

    private void interpretMessage(BufferedReader in, DataOutputStream out) throws IOException {
        BufferedWriter bw;
        BufferedReader br;
        String email;
        String password;
        String[] string;
        boolean existe;
        
        while (!interrupted()) {
            String auxMessage = null;
            try {
                DataOutputStream dos;
                message = in.readLine();
                auxMessage = message.split(":")[0];

                System.out.println("Mensagem " + auxMessage + " recebida de: " + connection.getInetAddress().toString());
                switch (auxMessage) {
                    case "UPDT"://Update File
                        System.out.println("IPClient: " + connection.getInetAddress());
                        Socket sock = new Socket(connection.getInetAddress(), 50400);
                        ObjectInputStream inputArc = new ObjectInputStream(new BufferedInputStream(sock.getInputStream()));
                        String fileName = inputArc.readUTF();
                        long size = inputArc.readLong();
                        BufferedOutputStream saveArq = new BufferedOutputStream(new FileOutputStream(fileName));
                        byte[] buf = new byte[4096];
                        int temp = 0;
                        while (true) {
                            int len;
                            if (size - temp > 0) {
                                len = inputArc.read(buf);
                            } else {
                                saveArq.close();
                                break;
                            }
                            temp = temp + len;
                            saveArq.write(buf, 0, len);
                            saveArq.flush();
                        }
                        bw = new BufferedWriter(new FileWriter("permissions" + File.separator + fileName));
                        bw.write("nobody");
                        bw.close();
                        System.out.println("Arquivo recebido " + fileName + " - " + size + " bytes.");
                        sock.close();
                        atendeCliente.receiveFile(connection);
                        for (int i = 0; i < serverList.size(); i++) {
                            dos = new DataOutputStream(serverList.get(i).getOutputStream());
                            dos.writeBytes("FU:" + fileName + "\n");
                        }
                        break;
                    case "GETF"://Get file
                        dos = new DataOutputStream(connection.getOutputStream());
                        dos.writeBytes("FILE\n");
                        ServerSocket welcome = new ServerSocket(50300);
                        Socket aux = welcome.accept();
                        atendeCliente.sendFile(aux, message.split(":")[1]);
                        aux.close();
                        welcome.close();
                        break;
                    case "PERM"://Permission to modify file
                        atendeCliente.permissionToModify(connection, message.split(":")[1], message.split(":")[2]);
                        break;
                    case "LOGN":
                        email = message.split(":")[1];
                        password = message.split(":")[2];
                        br = new BufferedReader(new FileReader("users.txt"));
                        existe = false;
                        while (br.ready()) {
                            string = br.readLine().split(":");
                            if (string[0].equals(email) && string[1].equals(password)) {
                                existe = true;
                                break;
                            }
                        }
                        if (existe) {
                            dos = new DataOutputStream(connection.getOutputStream());
                            dos.writeBytes("LACT\n");
                        } else {
                            dos = new DataOutputStream(connection.getOutputStream());
                            dos.writeBytes("LNEG\n");
                        }
                        break;
                    case "SGUP":
                        email = message.split(":")[1];
                        password = message.split(":")[2];
                        br = new BufferedReader(new FileReader("users.txt"));
                        existe = false;
                        while (br.ready()) {
                            string = br.readLine().split(":");
                            if (string[0].equals(email)) {
                                existe = true;
                                break;
                            }
                        }
                        if (!existe) {
                            bw = new BufferedWriter(new FileWriter("users.txt", true));
                            bw.append(email + ":" + password + "\n");
                            bw.close();
                            dos = new DataOutputStream(connection.getOutputStream());
                            dos.writeBytes("SCON\n");
                        } else {
                            dos = new DataOutputStream(connection.getOutputStream());
                            dos.writeBytes("SNEG\n");
                        }
                        break;
                }
            } catch (NullPointerException e) {
                atendeCliente.removeFromList(connection);
                in.close();
                out.close();
                connection.close();
                this.interrupt();
            }
        }
    }
}
